﻿#include "stdafx.h"
#include "SceneCharacterMgr.h"
#include "SceneMgr.h"
#include "PlayerMe.h"
#include "MuNetConnect.h"
#include "SceneMain.h"
#include "MainWin.h"

SceneCharacterMgr::SceneCharacterMgr()
{
	m_enableMouseCheck = true;
	m_lbtnDown = false;
	m_currFocusObj = nullptr;
	m_currSelectObj = nullptr;
}


SceneCharacterMgr::~SceneCharacterMgr()
{
}

bool SceneCharacterMgr::Init()
{
	bool fok;
	auto conn = MuNetConnect::GetInstance();
    conn->setListener(this);
	conn->RequestCharacterList();

	m_gui.InitWindow("characterMgr.layout");
	m_gui.m_cb_ok_btn = std::bind(&SceneCharacterMgr::cb_gui_btn_ok, this);

	auto wnd = MainWin::GetInstance();
	window_size_callback(wnd->GetWidth(), wnd->GetHeight());
	m_gameObjList1.SetRootMatrixPtr(&m_camera.GetViewMatrix());
	m_characterList.SetRootMatrixPtr(&m_camera.GetViewMatrix());

	fok = m_res.Load();
	auto shader_bone = &Shaders::GetInstance()->m_sBoneModel;
	auto logoBk = new SkeletonAnimation(&m_camera, &m_res.m_logoBackground, shader_bone);
    logoBk->SetLocalMatrix(glm::rotate(glm::translate(glm::mat4(1.0f), glm::vec3(-193.0f, 0.0f, 0.0f)), glm::radians(-10.0f), glm::vec3(0.0f, 0.0f, 1.0f)));
	logoBk->UseLight(1);
	m_gameObjList1.Add(logoBk);

	g_centerPoint = glm::vec3(-193.0f, -157.0f, -840.0f);
	g_scale = 45.0f;
	g_scale2 = -80.0f;

	return true;
}

bool SceneCharacterMgr::Res::Load()
{
	bool fok;
	m_texMgr.SetLoadDir("Data\\Logo\\");
	fok = Model::LoadSerialName(m_face, 4, "Data\\Logo\\face%02d.bmd", 1, &m_texMgr);
	if (!fok) Exit("Res::Load error: Data\\Logo\\face_n.bmd");

	fok = m_logoBackground.Load("Data\\Logo\\logo05.bmd", &m_texMgr);
	if (!fok) Exit("Res::Load error: Data\\Logo\\logo05.bmd");

	/*m_logoBackground.m_materials[0].m_blend = true;
	m_logoBackground.m_materials[0].m_blendDfactor = GL_ONE;
	m_logoBackground.m_materials[0].m_blendSfactor = GL_ONE;
	m_logoBackground.m_materials[1].m_blend = true;
	m_logoBackground.m_materials[1].m_blendDfactor = GL_ONE;
	m_logoBackground.m_materials[1].m_blendSfactor = GL_ONE;
	m_logoBackground.m_materials[2].m_blend = true;
	m_logoBackground.m_materials[2].m_blendDfactor = GL_ONE;
	m_logoBackground.m_materials[2].m_blendSfactor = GL_ONE;
	m_logoBackground.m_materials[3].m_blend = true;
	m_logoBackground.m_materials[3].m_blendDfactor = GL_ONE;
	m_logoBackground.m_materials[3].m_blendSfactor = GL_ONE;
	m_logoBackground.m_materials[4].m_blend = true;
	m_logoBackground.m_materials[4].m_blendDfactor = GL_ONE;
	m_logoBackground.m_materials[4].m_blendSfactor = GL_ONE;
	m_logoBackground.m_materials[5].m_blend = true;
	m_logoBackground.m_materials[5].m_blendDfactor = GL_ONE;
	m_logoBackground.m_materials[5].m_blendSfactor = GL_ONE;*/
	m_logoBackground.m_materials[6].m_blend = true;//小草
	//m_logoBackground.m_materials[6].m_blendDfactor = GL_ONE;
	//m_logoBackground.m_materials[6].m_blendSfactor = GL_ONE;
	m_logoBackground.m_materials[7].m_blend = true;//大草
	//m_logoBackground.m_materials[7].m_blendDfactor = GL_ONE;
	//m_logoBackground.m_materials[7].m_blendSfactor = GL_ONE;
	m_logoBackground.m_materials[8].m_blend = true;//树枝1
	//m_logoBackground.m_materials[8].m_depthTest = false;
	//m_logoBackground.m_materials[8].m_alphaTest = true;
	//m_logoBackground.m_materials[8].m_blendDfactor = GL_ONE;
	//m_logoBackground.m_materials[8].m_blendSfactor = GL_ONE;
	m_logoBackground.m_materials[9].m_blend = true;//树枝2
	//m_logoBackground.m_materials[9].m_blendDfactor = GL_ONE;
	//m_logoBackground.m_materials[9].m_blendSfactor = GL_ONE;
	m_logoBackground.m_materials[10].m_blend = true;//光线
	m_logoBackground.m_materials[10].m_blendDfactor = GL_ONE;
	m_logoBackground.m_materials[10].m_blendSfactor = GL_ONE;
	m_logoBackground.m_materials[10].m_depthTest = false;
	return true;
}

void SceneCharacterMgr::window_size_callback(int width, int height)
{
	m_viewport1.SetSize(width, height);
	m_viewport1.AspectRatio(4.0f / 3.0f);
	m_camera.Perspective(45, m_viewport1.m_width / (float)m_viewport1.m_height, 20, 2800);
	m_camera.SetViewMatrix(glm::rotate(
		glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -157.0f, -840.0f)),
        glm::radians(-80.0f), glm::vec3(1.0f, 0.0f, 0.0f)));
	Shaders::GetInstance()->m_fboColorPick.Viewport(m_viewport1.m_x, m_viewport1.m_y, m_viewport1.m_width, m_viewport1.m_height);
}

void SceneCharacterMgr::Update()
{
	m_viewport1.Use();
	//m_camera.Perspective(g_scale, m_viewport1.m_width / (float)m_viewport1.m_height, 20, 2800);
	//m_camera.SetViewMatrix(glm::rotate(
	//	glm::translate(g_centerPoint),
	//	g_scale2, 1.0f, 0.0f, 0.0f));
	m_gameObjList1.Update();
	m_characterList.Update();

	//if (m_mouseMove || m_lbtnDown)
	//if (m_lbtnDown)
	{
		auto win = MainWin::GetInstance();
		FboColorPick &fbo = Shaders::GetInstance()->m_fboColorPick;
		fbo.Clear();
		int count = m_characterList.GetCount();
		for (int i = 0; i < count; i++)
		{
			RenderObject *obj = (RenderObject*)m_characterList.GetGameObject(i);
			fbo.Add(obj->GetBoundBox());
		}
		//fbo.Draw(); return;
		UINT id = 0;
		BoundBoxObject *obj = fbo.Pick(win->GetMouseX() - m_viewport1.m_x, win->GetHeight() - win->GetMouseY());
		if (obj)
		{
			if (obj->m_objType == BoundBoxObject::ot_boundBox)
			{
				RenderObject *obj2 = ((RenderObject::BoundBox *)obj)->obj;
				if (m_lbtnDown)
				{
					if (obj2 != m_currSelectObj)
					{
						if (m_currSelectObj)
						{
							//if (m_currFocusObj) m_currFocusObj->OnFocus(false);
							m_currSelectObj->OnSelect(false);
						}
						m_currSelectObj = obj2;
						obj2->OnSelect(true);
					}
				}
				else
				{
					if (obj2 != m_currFocusObj)
					{
						if (m_currFocusObj)
						{
							m_currFocusObj->OnFocus(false);
						}
						m_currFocusObj = obj2;
						obj2->OnFocus(true);
					}
				}
			}
			
		}
		else if (m_currFocusObj)
		{
			m_currFocusObj->OnFocus(false);
			m_currFocusObj = nullptr;
		}
		//m_enableMouseCheck = false;
	}
}

void SceneCharacterMgr::cb_obj_focus(GameObject *obj, bool focus)
{
	auto ply = dynamic_cast<PlayerObject*>(obj);
	if (ply) ply->UseLight(focus ? 3 : 1);
}

void SceneCharacterMgr::cb_obj_select(GameObject *obj, bool select)
{
	auto ply = dynamic_cast<PlayerObject*>(obj);
	if (ply) ply->SetColor(select ? glm::vec4(1.0f,0.6f,0.6f,1.0f) : glm::vec4(1.0f));
}

void SceneCharacterMgr::on_cs_close()
{
    OutputInformation("cs connect close");
}

void SceneCharacterMgr::on_gs_close()
{
    OutputInformation("gs connect close");
}

void SceneCharacterMgr::on_gs_characterList(MuPack::CharacterList * characterList)
{
    float xpos[5] = { -220, -110, 0, 110, 220 };
    int pos;
    //FboColorPick &fbo = Shaders::GetInstance()->m_fboColorPick;
    //fbo.Clear();
    for (int i = 0; i < characterList->count; i++)
    {
        auto &ch = characterList->chars[i];
        pos = ch.position;
        auto obj = new PlayerMe;
        obj->SetId(pos);
        obj->Init((MuType::CharacterClass)(ch.muClass / 32), &m_camera, &Shaders::GetInstance()->m_sBoneModel);
        //obj->SetLocalMatrix(glm::rotate(
        //	glm::translate(glm::vec3((float)xpos[pos], -155.f, -855.f)),
        //	-90.0f, 1.0f, 0.0f, 0.0f));
        obj->SetPosition(xpos[pos], 0, 0);
        obj->m_animate.SetAnimation(1, 0);
        obj->SetId(0xff << (4 * i));
        obj->UseLight(1);
        obj->m_cb_focus = std::bind(&SceneCharacterMgr::cb_obj_focus, this, _1, _2);
        obj->m_cb_select = std::bind(&SceneCharacterMgr::cb_obj_select, this, _1, _2);
        obj->m_name = ch.name;
        obj->m_level = ch.level;
        m_characterList.Add(obj);
        //fbo.Add(obj);
        //auto mat = glm::rotate(
        //	glm::translate(glm::vec3((float)xpos[pos], -155.f, -855.f)),
        //	-90.0f, 1.0f, 0.0f, 0.0f);
        //GetTransformRoot(0)->AddChild(obj->m_transformObject.Add(mat));
        //m_gameObjects[0].push_back(obj);
    }
    OutputDebugStringA("character count:");
    dbgNum(characterList->count);
    //m_trans = ((PlayerObject*)GetGameObject(0, charList->chars[2].position))->m_transformObject.Get(0);
    g_centerPoint = glm::vec3(0.f, -155.f, -855.f);
    g_scale = 0.66;
}

void SceneCharacterMgr::cb_gui_btn_ok()
{
	if (m_currSelectObj)
	{
		auto obj = (PlayerMe*)m_currSelectObj;
		auto &ch = MuNetConnect::GetInstance()->m_currCharacter;
		strcpy(ch.name, obj->m_name.c_str());
		ch.level = obj->m_level;
		ch.muCls = obj->m_muClass;
		SceneMgr::GetInstance()->ReplaceScene(SceneMain::Create());
	}
}

void SceneCharacterMgr::mouse_button_callback(int button, int action, int mods)
{
	if (button == GLFW_MOUSE_BUTTON_LEFT)
	{
		m_lbtnDown=(action == GLFW_PRESS);
	}
}